<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Historywarn;
use App\Models\PriDeviceInfo;
use App\Models\WaterMyStorage;
use Carbon\Carbon;
use DB;
use Illuminate\Http\Request;
use Validator;
use App\Models\ReportSetting;
use App\Models\DeviceType;

class ReportController extends Controller
{

    protected $message = [

    ];

    /**
     * 历史告警统计
     *
     * @return array
     */
    public function index(Request $request)
    {

        $perPage = $request->input('pageSize', 15);

        $query = Historywarn::query();

        $pdiIndex = $request->input('pdi_index', '');

        if (!empty($pdiIndex)) {
            $query->where('pdi_index', '=', trim($pdiIndex));
        }

        $wdIndex = $request->input('wd_index', '');
        if (!empty($wdIndex)) {
            $query->where('wd_index', '=', trim($wdIndex));
        }

        $createdAt = $this->formatArrTime($request->input('rs_updatetime', ''));
        if (!empty($createdAt)) {
            $query->whereBetween('rs_updatetime', $createdAt);
        }
        $lvl = $request->input('lvl', '');
        if (!empty($lvl)) {
            $query->where('wd_level0', '=', trim($lvl));
        }

        $cid = $request->input('company', '');
        $sid = $request->input('site', '');
        $query->company($cid)->site($sid);
        $query
            ->leftJoin('t_warn_define', 't_warn_define.wd_index', '=', 't_historywarn.wd_index')
            ->select(['t_historywarn.*', 'wd_level0']);

        $query->with(['area'=>function($query){
                $query->select(['AreaId', 'AreaName', 'area_text']);
        }]);

        $warns = $query->paginate($perPage);

        return $this->success('', ['data' => $warns]);
    }

    /**
     * 历史统计
     * @param Request $request
     * @return array
     */
    public function historysum(Request $request)
    {

        $query = Historywarn::query();

        $pdiIndex = $request->input('pdi_index', '');

        if (!empty($pdiIndex)) {
            $query->where('pdi_index', '=', trim($pdiIndex));
        }

        $createdAt = $request->input('rs_updatetime', '');
        $dates = $this->getTime($createdAt, ['7 days ago', 'today']);

        if (!empty($dates)) {
            $query->whereBetween('rs_updatetime', $dates);
        }

        $query
            ->groupBy(['pdi_index', 'wd_level0'])
            ->leftJoin('t_warn_define', 't_warn_define.wd_index', '=', 't_historywarn.wd_index')
            ->select(['pdi_index', 't_historywarn.wd_index', 'pdi_name as name', 'wd_level0', DB::raw('count(t_historywarn.wd_index) as value')]);

        $warns = $query->get();

        return $this->success('', ['data' => $warns, 'rs_updatetime' => $dates]);
    }

    /**
     * 资产统计
     * @param Request $request
     * @return array
     */
    public function assetsum(Request $request)
    {

        $query = PriDeviceInfo::query();

        $query
            ->leftJoin('t_devicetype', 't_devicetype.dt_typeid', '=', 't_prideviceinfo.dpt_id')
            ->select(['pdi_index', 'dpt_id', 'pdi_name', 'dt_typename', 'dt_typememo']);

        $query->whereIn('t_prideviceinfo.dpt_id', config('water.device'));

        $pdi = $query->get();

        $result = [];

        $group = $pdi->groupBy('dpt_id');
        $pdiType = $pdi->pluck('dt_typememo', 'dpt_id');

        foreach ($pdiType as $key => $val) {
            $result[] = ['value' => count($group[$key]), 'name' => $val, 'device' => $group[$key], 'dpt_id' => $key];
        }

        return $this->success('', ['data' => $result, 'total' => $pdi->count()]);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {

    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {

    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {

    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {

    }

    protected function validateData($request)
    {

    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {

    }

    /**
     * 获取时间
     * @param type $dates
     * @param type $defaults
     * @return array
     */
    protected function getTime($dates, $defaults = ['7 days ago', 'today'])
    {

        if (!$dates) {
            $dates = $defaults;
        }

        list($startDay, $endDay) = $dates;

        $zhStart = Carbon::parse($startDay)->startOfDay()->toDateTimeString();

        $zhEnd = Carbon::parse($endDay)->endOfDay()->toDateTimeString();

        return [$zhStart, $zhEnd];
    }

    // 日报
    public function water(Request $request)
    {

        $cid = $request->input('company');
        $sid = $request->input('site');
        $date = $request->input('searchDate');

        $dptId = $request->input('dpt_id');

        $pdi = $request->input('pdi');

        $config = ReportSetting::where('device_type', $dptId)->first();

        if(!$config) {
            return ['data' => [], 'columns' => []];
        }

        $table = $config->report_table_name;
        
        $columns = $config->settingField()->select(['sum_field as prop', 'sum_desc as label', 'is_inc'])->get();

        if ($pdi && $date) {
            $real = $this->getDayHours($pdi, $table, $date, $columns);
        } else {
            $real = $this->getDayReal($cid, $sid, $table, $columns, $dptId);
        }

        return ['data' => $real, 'columns' => $columns];
    }

    //获取24小时数据
    protected function getDayHours($pdi, $defineTable, $date, $columns)
    {

        $table =  str_replace('t_hisdata', 't_hour', $defineTable);

        $date = Carbon::parse($date)->toDateString();

        $list = DB::table($table)
            ->select([$table . '.*', 'pdi_name', 'area_text as name'])
            ->where($table . '.pdi_index', $pdi)
            ->where('at_date', $date)
            ->leftJoin('t_prideviceinfo', $table . '.pdi_index', '=', 't_prideviceinfo.pdi_index')
            ->leftJoin('sy_area', 't_prideviceinfo.AreaId', '=', 'sy_area.AreaId')
            ->get()
            ->sortBy('hour')->values();

        return $list;
    }

    //获取所有站点实时数据
    protected function getDayReal($cid, $sid, $defineTable, $columns, $dptId)
    {
        //公司所有站点
        $fields = $columns->pluck('prop')->all();

        $table = str_replace('t_hisdata', 't_realdata', $defineTable);

        $info = PriDeviceInfo::where('dpt_id', $dptId)
            ->company($cid)
            ->site($sid)
            ->select(['t_prideviceinfo.pdi_index', 'AreaId', 'pdi_name', 'rd_updatetime', $table . '.*'])
            ->join($table, $table . '.pdi_index', '=', 't_prideviceinfo.pdi_index')
            ->with([
                'area' => function ($query) {
                    $query->select(['AreaId', 'AreaName', 'area_text']);
                },
            ])
            ->get();

        $real = [];

        foreach ($info as $v) {
            $temp = [
                'pdi_index' => $v->pdi_index,
                'name' => data_get($v, 'area.area_text'),
                'pdi_name' => data_get($v, 'pdi_name'),
                'time' => data_get($v, 'rd_updatetime'),
            ];

            foreach ($fields as $vv) {
                $fieldKey = "rd_{$vv}";
                $temp[$vv] = data_get($v, $fieldKey, 0);
            }
            $real[] = $temp;
        }
        return $real;
    }
    // 月报
    public function monthWater(Request $request, $month)
    {
        if (!$month) {
            $this->error('缺少日期参数');
        }
        $cid = $request->input('company');
        $sid = $request->input('site');
        $dptId = $request->input('dpt_id');

        $messages = [
            'month.required' => '日期参数必须',
            'month.regex' => '日期格式不正确',
            'dpt_id.required' => '设备分类参数必须',
        ];
        $rules = [
            'month' => ['required', 'regex:/^\d{4}-\d{2}$/'],
            'dpt_id'=>'required'
        ];
        $inputs = ['month' => $month, 'dpt_id'=>$dptId];

        Validator::make($inputs, $rules, $messages)->validate();

        $parseDate = Carbon::parse($month);

        $monthRange = [$parseDate->startOfMonth()->toDateString(), $parseDate->endOfMonth()->toDateString()];


        $pdi = $request->input('pdi');

        $config = ReportSetting::where('device_type', $dptId)->first();
        
        if(!$config) {
            return ['data' => [], 'columns' => []];
        }

        $table = $config->report_table_name;

        $monthTable = str_replace('t_hisdata', 't_month', $table);
        
        $columns = $config->settingField()->select(['sum_field as prop', 'sum_desc as label', 'is_inc'])->get();

        $data = DB::table($monthTable)
            ->whereBetween('at_date', $monthRange)
            ->where('pdi_index', $pdi)
            ->get()
            ->sortBy('at_date')
            ->map(function ($item) use ($columns) {
                foreach ($columns as $v) {
                    $item->{$v->prop} = $this->getMonthData($v, $item);
                }
                return $item;
            });


        return ['data' => $data, 'columns' => $columns];
    }

    //计算月报数据
    protected function getMonthData($field, $item)
    {
        $current = $field->prop;
        if ($field->is_inc==1) {
            return $item->{$current};
        }
        return round($item->{$current} / $item->num, 2);
    }

    //生成水质报告
    public function genwater()
    {

    }

    //获取药品查询时间
    protected function getYpTime($searchDate, $type)
    {
        $zhStart = Carbon::parse($searchDate);
        $zhEnd = Carbon::parse($searchDate);

        $date = [];
        switch ($type) {
            case 'day':
                $date = [$zhStart->startOfDay()->toDateTimeString(), $zhEnd->endOfDay()->toDateTimeString()];
                break;
            case 'week':
                $start = $zhStart->startOfWeek(Carbon::MONDAY);
                $end = $zhEnd->endOfWeek(Carbon::SUNDAY);
                $date = [$start->toDateTimeString(), $end->toDateTimeString()];
                break;
            case 'month':
                $date = [$zhStart->startOfMonth()->toDateTimeString(), $zhEnd->endOfMonth()->toDateTimeString()];
                break;
            case 'year':
                $date = [$zhStart->startOfYear()->toDateTimeString(), $zhEnd->endOfYear()->toDateTimeString()];
                break;
            default:
                break;
        }
        return $date;
    }
    //药品统计
    protected function sumYaoping($request, $format, $dates)
    {
        // $format = $type=="month"?"%Y-%m":"%Y-%m-%d";

        $cid = $request->input('company');
        $sid = $request->input('site');

        $query = WaterMyStorage::query();
        $query->where('water_my_storages.company_id', $cid);
        $query->where('water_my_storages.site_id', $sid);
        $query->whereBetween('water_storage_out_shops.created_at', $dates);
        $list = $query
            ->leftJoin('water_storage_out_shops', 'water_my_storages.id', '=', 'water_storage_out_shops.water_my_storage_id')
            ->leftJoin('water_shops', 'water_my_storages.shop_id', '=', 'water_shops.id')
            ->select('water_my_storages.company_id', 'water_my_storages.site_id', 'shop_id',
                'water_shops.name', DB::raw('sum(out_num) as out_num'),
                DB::raw("date_format(water_storage_out_shops.created_at, '$format') as out_date")
            )
            ->groupBy('water_my_storages.company_id', 'water_my_storages.site_id', 'shop_id', 'out_date')
            ->with([
                'companies' => function ($query) {
                    $query->select(['Co_ID', 'Co_Name']);
                },
                'sites' => function ($query) {
                    $query->select(['id', 'name']);
                },
            ])
            ->get();
        return ['data' => $list];
    }

    //药品日消耗统计
    public function yaoping(Request $request)
    {
        $searchDate = $request->input('searchDate', date('Y-m-d'));
        $dates = $this->getYpTime($searchDate, 'day');
        $format = "%Y-%m-%d";
        return $this->sumYaoping($request, $format, $dates);
    }

    //药品月消耗统计
    public function yaopingMonth(Request $request)
    {
        $searchDate = $request->input('searchDate', date('Y-m-d'));
        $dates = $this->getYpTime($searchDate, 'month');
        $format = "%Y-%m";
        return $this->sumYaoping($request, $format, $dates);
    }
}
